/**
 * Carnegie Mellon University
 * School of Computer Science
 * MSIT eBusiness Technology
 * 
 * Team 8 - Infinity (2011 Spring)
 * infinity-team8@googlegroups.com
 * 
 * Professor: Jeffrey L. Eppinger
 * Program Faculty: Sujata Telang
 */

package model;

import java.util.Arrays;

import org.mybeans.dao.DAOException;
import org.mybeans.factory.BeanFactory;
import org.mybeans.factory.BeanFactoryException;
import org.mybeans.factory.BeanTable;
import org.mybeans.factory.DuplicateKeyException;
import org.mybeans.factory.MatchArg;
import org.mybeans.factory.RollbackException;
import org.mybeans.factory.Transaction;

import databean.FundBean;


public class FundDAO {
	private BeanFactory<FundBean> factory;
	
	public FundDAO() throws DAOException {
		try {
			// Get a BeanTable so we can create the "user" table
	        BeanTable<FundBean> fundTable = BeanTable.getInstance(FundBean.class,"fund");
	        
	        if (!fundTable.exists()) fundTable.create("fundID");
	        
	        // Long running web apps need to clean up idle database connections.
	        // So we can tell each BeanTable to clean them up.  (You would only notice
	        // a problem after leaving your web app running for several hours.)
	        fundTable.setIdleConnectionCleanup(true);
	
	        // Get a BeanFactory which the actions will use to read and write rows of the "user" table
	        factory = fundTable.getFactory();
	        
	        
	        //create pre-defined fund 1
	        if (lookup("CHASX") == null)
	        {
		        //insert three users as a default when creating the user table
		        try {
	
		        	Transaction.begin();

		        	FundBean dbFund = factory.create();
		        	dbFund.setName("Chase Growth N");
		        	dbFund.setSymbol("CHASX");

		        	Transaction.commit();
	
				} catch (DuplicateKeyException e) {
					throw new DAOException("Symbol 'CHASX' already exists");
				} catch (RollbackException e) {
					throw new DAOException(e);
				} finally {
					if (Transaction.isActive()) Transaction.rollback();
				}
	        }
	        
	        
	        //create pre-defined fund 2
	        if (lookup("AGTHX") == null)
	        {
		        //insert three users as a default when creating the user table
		        try {
	
		        	Transaction.begin();
		        	factory = fundTable.getFactory();

		        	FundBean dbFund = factory.create();
		        	dbFund.setName("American Funds Growth Fund of Amer A");
		        	dbFund.setSymbol("AGTHX");
		        	
		        	Transaction.commit();
	
				} catch (DuplicateKeyException e) {
					throw new DAOException("Symbol 'AGTHX' already exists");
				} catch (RollbackException e) {
					throw new DAOException(e);
				} finally {
					if (Transaction.isActive()) Transaction.rollback();
				}
	        }
	        
	        
	        //create pre-defined fund 3
	        if (lookup("VFINX") == null)
	        {
		        //insert three users as a default when creating the user table
		        try {
	
		        	Transaction.begin();
		        	factory = fundTable.getFactory();
		        	
		        	FundBean dbFund = factory.create();
		        	dbFund.setName("Vanguard 500 Index");
		        	dbFund.setSymbol("VFINX");
		        	
		        	Transaction.commit();
	
				} catch (DuplicateKeyException e) {
					throw new DAOException("Symbol 'VFINX' already exists");
				} catch (RollbackException e) {
					throw new DAOException(e);
				} finally {
					if (Transaction.isActive()) Transaction.rollback();
				}
	        }
	        
	        
	        
		} catch (BeanFactoryException e) {
			throw new DAOException(e);
		}
	}
	
	public void create(FundBean fund) throws DAOException {
		try {

        	if (lookup(fund.getSymbol())==null) {
        			        	
	        	Transaction.begin();
	        	
	        	FundBean dbFund = factory.create();
				factory.copyInto(fund,dbFund);
				
				Transaction.commit();
	        	
        	} else {
        		
        		throw new DuplicateKeyException("A symbol named "+fund.getSymbol()+" already exists");
        		
        	}
			
		} catch (DuplicateKeyException e) {
			throw new DAOException("A symbol named "+fund.getSymbol()+" already exists");
		} catch (RollbackException e) {
			throw new DAOException(e);
		} finally {
			if (Transaction.isActive()) Transaction.rollback();
		}
	}
	
	/**
	 * lookup fund by fund id
	 * @param name
	 * @return
	 * @throws DAOException
	 */
	public FundBean lookup(long fundID) throws DAOException {
		try {
			return factory.lookup(fundID);
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}
	
	
	/**
	 * lookup fund by symbol
	 * @param name
	 * @return
	 * @throws DAOException
	 */
	public FundBean lookup(String symbol) throws DAOException {
		try {
			
			if (factory.match(MatchArg.equals("symbol", symbol)) == null ||
            		factory.match(MatchArg.equals("symbol", symbol)).length == 0) {
				return null;
			} else {
				return factory.match(MatchArg.equals("symbol", symbol))[0];
			}
			
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}
	
	
	
	
	protected BeanFactory<FundBean> getFactory() { return factory; }
	
	public FundBean[] getFunds() throws DAOException {
		try {
			FundBean[] funds = factory.match();
			Arrays.sort(funds);
			return funds;
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}
	
}
